/*
 * KKLayout.h
 *
 *  Created on: 2013-9-15
 *      Author: wanghua
 */

#ifndef KKLAYOUT_H_
#define KKLAYOUT_H_

#include "kaka_common.h"
#include "KKNode.h"

USING_NS_CC;

typedef enum {
	KKAlignmentNone,
	KKAlignmentLeft,
	KKAlignmentCenter,
	KKAlignmentRight,
	KKAlignmentTop,
	KKAlignmentBottom
} KKNodeAlignment;

class KKLayout: public CCObject {

private:
	;CC_SYNTHESIZE(KKNodeAlignment,m_hAlign,HAlign)
	;CC_SYNTHESIZE(KKNodeAlignment,m_vAlign,VAlign)

	;CC_SYNTHESIZE(float,m_marginLeft,MarginLeft)
	;CC_SYNTHESIZE(float,m_marginRight,MarginRight)
	;CC_SYNTHESIZE(float,m_marginTop,MarginTop)
	;CC_SYNTHESIZE(float,m_marginBottom,MarginBottom)

	;CC_SYNTHESIZE(float,m_paddingLeft,PaddingLeft)
	;CC_SYNTHESIZE(float,m_paddingRight,PaddingRight)
	;CC_SYNTHESIZE(float,m_paddingTop,PaddingTop)
	;CC_SYNTHESIZE(float,m_paddingBottom,PaddingBottom)

	;CC_SYNTHESIZE(float,m_weight,Weight)

public:
	int getChildWidth(KKNode* node);

	int getChildHeight(KKNode* node);

public:
	KKLayout();
	virtual ~KKLayout();

	virtual void initFromXml(TiXmlElement* element);

	virtual void measureChild(KKNode* child, const float& measureWidth,
			const float& measureHeight);

	virtual void measure(KKNode* node, KKNodeArray* children);

	virtual void layout(KKNode* node, KKNodeArray* children)=0;
};

class KKLayoutParser: public CCObject {
private:
	static KKDictionary<string, KKLayoutParser*> m_parsers;
public:
	static void registerParser(const char* className, KKLayoutParser* parser) {
		m_parsers.setObject(parser, className);
	}

	static KKLayout* parseFromXml(TiXmlElement* element);

	virtual KKLayout* parse(TiXmlElement* element)=0;
};

#define KKLAYOUT_PARSER_CLASS(parserClass,className) \
		class parserClass: public KKLayoutParser {\
			KKLayout* parse(TiXmlElement* element) {\
				return className::createFromXml(element);\
			}\
		};

class AbsLayout: public KKLayout {

public:
	AbsLayout() {
	}
	virtual ~AbsLayout() {
	}
	;

	static AbsLayout* createFromXml(TiXmlElement* element);

	virtual void layout(KKNode* node, KKNodeArray* children);
};

KKLAYOUT_PARSER_CLASS(AbsLayoutParser, AbsLayout)

class RelativeLayout: public KKLayout {

public:
	RelativeLayout() {
	}
	;
	virtual ~RelativeLayout() {
	}
	;

	static RelativeLayout* createFromXml(TiXmlElement* element);

	virtual void layout(KKNode* node, KKNodeArray* children);
};

KKLAYOUT_PARSER_CLASS(RelativeLayoutParser, RelativeLayout);

class LinearLayout: public KKLayout {
private:

	;CC_SYNTHESIZE(int,m_vgap,VGap)
	;
	;CC_SYNTHESIZE(int,m_hgap,HGap)
	;
	;CC_SYNTHESIZE_READONLY(KKNodeAlignment,m_hGravity,HGravity)
	;CC_SYNTHESIZE_READONLY(KKNodeAlignment,m_vGravity,VGravity)
	;CC_SYNTHESIZE(bool,m_vertical,IsVertical)
	;

public:
	LinearLayout() {
		m_vgap = 0;
		m_hgap = 0;
		m_hGravity = KKAlignmentLeft;
		m_vGravity = KKAlignmentBottom;
		m_vertical = false;
	}
	;
	virtual ~LinearLayout() {
	}
	;

	static LinearLayout* createFromXml(TiXmlElement* element);

	virtual void layout(KKNode* node, KKNodeArray* children);

	void measureVertical(KKNode* node, KKNodeArray* children,
			const float & measurewidth, const float & measureHeight);

	virtual void measure(KKNode* node, KKNodeArray* children);

	void layoutVertical(KKNode* node, KKNodeArray* children, const int & width,
			const int & height);

	void layoutHorizontal(KKNode* node, KKNodeArray* children,
			const int & width, const int & height);
};

KKLAYOUT_PARSER_CLASS(LinearLayoutParser, LinearLayout)

typedef enum {
	FITXY, CENTER_INSIDE, CENTER_CROP, SCALE_NO
} KKScaleType;

class GridLayout: public KKLayout {
private:
	;CC_SYNTHESIZE(int,m_cellWidth,CellWidth)
	;
	;CC_SYNTHESIZE(int,m_cellHeight,CellHeight)
	;
	;CC_SYNTHESIZE(int,m_column,Column)
	;
	;CC_SYNTHESIZE(int,m_vgap,VGap)
	;
	;CC_SYNTHESIZE(int,m_hgap,HGap)
	;
	;CC_SYNTHESIZE(KKScaleType,m_scaleType,ScaleType)
	;
	;CC_SYNTHESIZE_READONLY(KKNodeAlignment,m_hGravity,HGravity)
	;CC_SYNTHESIZE_READONLY(KKNodeAlignment,m_vGravity,VGravity)
public:
	GridLayout() {
		m_cellWidth = 100;
		m_cellHeight = 100;
		m_column = 1;
		m_vgap = 0;
		m_hgap = 0;
		m_scaleType = SCALE_NO;
		m_hGravity = KKAlignmentLeft;
		m_vGravity = KKAlignmentTop;
	}
	;
	virtual ~GridLayout() {
	}
	;

	static GridLayout* createFromXml(TiXmlElement* element);

	virtual void layout(KKNode* node, KKNodeArray* children);

};

KKLAYOUT_PARSER_CLASS(GridLayoutParser, GridLayout);
#endif /* KKLAYOUT_H_ */
